home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / port / sunos4 / dynloader.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  4.5 KB  |  224 lines

  1. /*
  2.  
  3. !!!! Be sure that we close all open files up exit on the Sequent - the ld !!!!
  4.      fails otherwise 
  5.  
  6.      $Header: /private/postgres/src/port/sunos4/RCS/dynloader.c,v 1.14 1992/01/12 23:30:23 mao Exp $
  7. */
  8.  
  9. #include <pwd.h>
  10. #include <stdio.h>
  11. #include <sys/types.h>
  12. #include <sys/param.h>
  13. #include <sys/stat.h>
  14. #include <sys/file.h>
  15.  
  16. extern char pg_pathname[];
  17.  
  18. #include <a.out.h>
  19.  
  20. #include "tmp/c.h"
  21. #include "utils/fmgr.h"
  22.  
  23. /*
  24.  * Allow extra space for "overruns" caused by the link.
  25.  */
  26.  
  27. #define FUDGE 10000
  28.  
  29. static char *temp_file_name = NULL;
  30. static char *path = "/usr/tmp/postgres";
  31.  
  32. DynamicFunctionList *
  33. dynamic_file_load(err, filename, address, size)
  34.  
  35. char **err, *filename, **address;
  36. long *size;
  37.  
  38. {
  39.     extern char *valloc();
  40.  
  41.     int nread;
  42.     struct exec ld_header, header;
  43.     unsigned long image_size, true_image_size;
  44.     char *load_address = NULL;
  45.     FILE *temp_file = NULL;
  46.     DynamicFunctionList *retval = NULL, *load_symbols();
  47.     int fd;
  48.     char foo[10];
  49.  
  50.     fd = open(filename, O_RDONLY);
  51.  
  52.     if (fd == -1)
  53.     {
  54.         *err = "error opening file";
  55.         goto finish_up;
  56.     }
  57.  
  58.     read(fd, &ld_header, sizeof(struct exec));
  59.  
  60.     image_size = ld_header.a_text + ld_header.a_data + ld_header.a_bss + FUDGE;
  61.  
  62.     close(fd); /* don't open it until the load is finished. */
  63.  
  64.     if (!(load_address = valloc(image_size)))
  65.     {
  66.         *err = "unable to allocate memory";
  67.         goto finish_up;
  68.     }
  69.  
  70.     if (temp_file_name == NULL)
  71.     {
  72.         sprintf(foo, "%d", getpid());
  73.         temp_file_name = (char *)malloc(strlen(path) + strlen(foo) + 2);
  74.         strcpy(temp_file_name, path);
  75.         strcat(temp_file_name, foo);
  76.     }
  77.  
  78.     if(execld(load_address, temp_file_name, filename))
  79.     {
  80.         *err = "link failed!";
  81.         goto finish_up;
  82.     }
  83.  
  84.     if(!(temp_file = fopen(temp_file_name,"r")))
  85.     {
  86.         *err = "unable to open tmp file";
  87.         goto finish_up;
  88.     }
  89.     nread = fread(&header, sizeof(header), 1, temp_file);
  90.     true_image_size = header.a_text + header.a_data + header.a_bss;
  91.  
  92.     if (true_image_size > image_size)
  93.     {
  94.         fclose(temp_file);
  95.         free(load_address);
  96.         load_address = valloc(true_image_size);
  97.  
  98.         if (execld(load_address, temp_file_name, filename))
  99.         {
  100.             *err = "ld failed!";
  101.             goto finish_up;
  102.         }
  103.         temp_file = fopen(temp_file_name,"r");
  104.         nread = fread(&header, sizeof(header), 1, temp_file);
  105.     }
  106.  
  107.     fseek(temp_file, N_TXTOFF(header), 0);
  108.     nread = fread(load_address, true_image_size,1,temp_file);
  109.  
  110.     retval = load_symbols(filename, &ld_header, load_address);
  111.  
  112.     fclose(temp_file);
  113.     unlink(temp_file_name);
  114.     *address = load_address;
  115.     *size = image_size;
  116.  
  117.     temp_file = NULL;
  118.     load_address = NULL;
  119.  
  120. finish_up:
  121.     if (temp_file != NULL) fclose(temp_file);
  122.     if (load_address != NULL) free(load_address);
  123.     return retval;
  124. }
  125.  
  126. DynamicFunctionList *
  127. load_symbols(filename, hdr, entry_addr)
  128.  
  129. char *filename;
  130. struct exec *hdr;
  131. int entry_addr;
  132.  
  133. {
  134.     int fd;
  135.     char *strings, *symb_table, *p, *q;
  136.     int symtab_offset, string_offset, string_size, nsyms, i;
  137.     struct nlist *table_entry;
  138.     int entering = 1;
  139.     DynamicFunctionList *head, *scanner;
  140.  
  141.     symtab_offset = N_SYMOFF(*hdr);
  142.     string_offset = N_STROFF(*hdr);
  143.  
  144.     fd = open(filename, O_RDONLY);
  145.  
  146.     lseek(fd, string_offset, 0);
  147.     read(fd, &string_size, sizeof(string_size));
  148.     strings = (char *) malloc(string_size - 4);
  149.     read(fd, strings, string_size - 4);
  150.     nsyms = hdr->a_syms / sizeof(struct nlist);
  151.     lseek(fd, symtab_offset, 0);
  152.     symb_table = (char *) malloc(hdr->a_syms);
  153.     read(fd, symb_table, hdr->a_syms);
  154.  
  155.     p = symb_table;
  156.     for (i = 0; i < nsyms; i++)
  157.     {
  158.         table_entry = (struct nlist *) p;
  159.         p += sizeof(struct nlist);
  160.         if (! ((table_entry->n_type & N_EXT) == 0
  161.             || (table_entry->n_type & N_TYPE) != N_TEXT))
  162.         {
  163.             if (entering)
  164.             {
  165.                 head = (DynamicFunctionList *)
  166.                        malloc(sizeof(DynamicFunctionList));
  167.                 scanner = head;
  168.                 entering = 0;
  169.             }
  170.             else
  171.             {
  172.                 scanner->next = (DynamicFunctionList *)
  173.                                 malloc(sizeof(DynamicFunctionList));
  174.                 scanner = scanner->next;
  175.             }
  176.             /*
  177.              * Add one for "_", ie
  178.              * overpaid() will be _overpaid
  179.              */
  180.  
  181.             q = strings + (table_entry->n_un.n_strx - 4) + 1;
  182.  
  183.             strcpy(scanner->funcname, q);
  184.             scanner->func = (func_ptr) (table_entry->n_value + entry_addr);
  185.             scanner->next = NULL;
  186.         }
  187.     }
  188.  
  189.     free(symb_table);
  190.     free(strings);
  191.     close(fd);
  192.     return(head);
  193. }
  194.  
  195. func_ptr
  196. dynamic_load(err)
  197.  
  198. char **err;
  199.  
  200. {
  201.     *err = "Dynamic load: Should not be here!";
  202.     return(NULL);
  203. }
  204.  
  205. /* 
  206.  *   ld -N -x -A SYMBOL_TABLE -T ADDR -o TEMPFILE FUNC -lc
  207.  */
  208.  
  209. execld(address, tmp_file, filename)
  210.  
  211. char *address, *tmp_file, *filename;
  212.  
  213. {
  214.     char command[256];
  215.     int retval;
  216.  
  217.     sprintf(command,"ld -N -x -A %s -T %lx -o %s  %s -lc -lm -ll",
  218.             pg_pathname,
  219.             address,
  220.             tmp_file,  filename);
  221.     retval = system(command);
  222.     return(retval);
  223. }
  224.